package com.swu.pad.course.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.swu.pad.assignment.entity.Assignment;
import com.swu.pad.assignment.service.AssignmentService;
import com.swu.pad.course.dao.CourseDao;
import com.swu.pad.course.dao.CourseGroupUserDao;
import com.swu.pad.course.dao.GroupDao;
import com.swu.pad.course.dto.Student;
import com.swu.pad.course.entity.Course;
import com.swu.pad.course.entity.CourseGroupUser;
import com.swu.pad.course.entity.Group;
import com.swu.pad.course.service.CourseGroupUserService;
import com.swu.pad.course.service.CourseService;
import com.swu.pad.course.service.GroupService;
import com.swu.pad.system.entity.User;
import com.swu.pad.system.service.UserService;
import com.swu.pad.util.StringUtil;
import com.swu.pad.util.ExcelUtils.CsvReader;

@Service
@Transactional
public class CourseServiceImpl implements CourseService {

	@Autowired
	private CourseDao courseDao;
	@Autowired
	private GroupDao groupDao;
	@Autowired
	private CourseGroupUserDao courseGroupUserDao;
	@Autowired
	private UserService userService;
	@Autowired
	private GroupService groupService;
	@Autowired
	private CourseGroupUserService courseGroupUserService;
	@Autowired
	private AssignmentService assignmentService;

	public Course addCourse(Course course) {
		course.setCreateTime(new Date());
		return courseDao.saveAndFlush(course);
	}

	@Transactional(rollbackFor = Exception.class)
	public void deleteCourse(String courseId) {
		// 删除课程，同时删除组
		List<Group> groupList = groupDao.findGroupByCourseId(courseId);
		for (int i = 0; i < groupList.size(); i++) {
			groupService.deleteGroup(groupList.get(i).getId());
		}
		courseDao.delete(courseId);
	}

	public List<Course> getAllCourses() {
		return courseDao.findAll();
	}

	public Course getCourseById(String courseId) {
		return courseDao.findCourseById(courseId);
	}

	public Map<String, Object> getCourseDetail(String courseId) {
		// {course:{},studentCount:22,groupCount:3,groups:[{groupName:"",groupMember:[{userId:"",userName:""}]}]}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("course", courseDao.findCourseById(courseId));

		List<CourseGroupUser> courseGroupUserList = courseGroupUserDao.findCourseGroupUserByCourseIdAndGroupType(courseId, Group.TYPE_GROUP);
		map.put("studentCount", courseGroupUserList.size());

		List<Group> groupList = groupDao.findGroupByCourseIdAndGroupType(courseId, Group.TYPE_GROUP);
		map.put("groupCount", groupList.size());
		List<Object> groupMapList = new ArrayList<Object>();
		for (Group group : groupList) {
			Map<String, Object> tempMap = new HashMap<String, Object>();
			tempMap.put("groupName", group.getGroupName());

			List<CourseGroupUser> groupUserList = courseGroupUserDao.findCourseGroupUserByGroupId(group.getId());
			List<Object> userMapList = new ArrayList<Object>();
			for (CourseGroupUser user : groupUserList) {
				Map<String, Object> tempUserMap = new HashMap<String, Object>();
				tempUserMap.put("userId", user.getUserId());
				tempUserMap.put("userName", user.getUserName());
				userMapList.add(tempUserMap);
			}
			tempMap.put("groupMember", userMapList);
			groupMapList.add(tempMap);
		}
		map.put("groups", groupMapList);
		return map;
	}

	@Transactional(rollbackFor = Exception.class)
	public void importStudent(Course course, MultipartFile file) {
		try {
			// List<Map<String, String>> list = ExcelReader.readRromExcel(file);
			List<Map<String, String>> list = CsvReader.readCsv(file.getInputStream());
			for (int i = 0; i < list.size(); i++) {
				Map<String, String> map = list.get(i);
				String studentNum = map.get("学号");
				String name = map.get("姓名");
				String email = map.get("邮箱");
				String groupNum = map.get("小组作业组号");
				String commentGroups = map.get("小组作业互评组号");
				String singleNum = map.get("个人作业编号");
				String commentSingleGroups = map.get("个人作业互评号");

				// 创建用户
				User user = new User();
				user.setUsername(studentNum);
				user.setPassword("000000");
				user.setRealname(name);
				user.setEmail(email);
				user.setRole(User.ROLE_STUDENT);
				user = userService.saveUser(user);

				// 创建组
				Group group = new Group();
				group.setCourseId(course.getId());
				group.setGroupNum(groupNum);
				group.setGroupName("小组" + groupNum);
				group.setGroupType(Group.TYPE_GROUP);
				group.setCommentGroups(commentGroups);
				group = groupService.addGroup(group);

				// 关联组和用户
				CourseGroupUser courseGroupUser = new CourseGroupUser();
				courseGroupUser.setCourseId(course.getId());
				courseGroupUser.setCourseName(course.getCourseName());
				courseGroupUser.setGroupId(group.getId());
				courseGroupUser.setGroupName(group.getGroupName());
				courseGroupUser.setGroupType(Group.TYPE_GROUP);
				courseGroupUser.setUserId(user.getId());
				courseGroupUser.setUserName(user.getRealname());
				courseGroupUserService.addCourseGroupUser(courseGroupUser);

				// 创建个人组
				if (StringUtil.isValid(singleNum)) {
					Group singleGroup = new Group();
					singleGroup.setCourseId(course.getId());
					singleGroup.setGroupNum(singleNum);
					singleGroup.setGroupName("个人" + singleNum);
					singleGroup.setGroupType(Group.TYPE_SINGLE);
					singleGroup.setCommentGroups(commentSingleGroups);
					singleGroup = groupService.addGroup(singleGroup);

					CourseGroupUser courseSingleGroupUser = new CourseGroupUser();
					courseSingleGroupUser.setCourseId(course.getId());
					courseSingleGroupUser.setCourseName(course.getCourseName());
					courseSingleGroupUser.setGroupId(singleGroup.getId());
					courseSingleGroupUser.setGroupName(singleGroup.getGroupName());
					courseSingleGroupUser.setGroupType(Group.TYPE_SINGLE);
					courseSingleGroupUser.setUserId(user.getId());
					courseSingleGroupUser.setUserName(user.getRealname());
					courseGroupUserService.addCourseGroupUser(courseSingleGroupUser);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public List<Course> getStudentCourse(String userId) {
		List<CourseGroupUser> list = courseGroupUserDao.findCourseGroupUserByUserId(userId);
		Set<String> set = new HashSet<String>();
		for (int i = 0; i < list.size(); i++) {
			set.add(list.get(i).getCourseId());
		}
		List<Course> courseList = new ArrayList<Course>();
		for (String courseId : set) {
			courseList.add(courseDao.findOne(courseId));
		}
		return courseList;
	}

	public List<Course> getTeacherCourse(String userId) {
		return courseDao.findCourseByTeacherId(userId);
	}

	public List<Group> getCourseGroup(String courseId, String groupType) {
		return groupDao.findGroupByCourseIdAndGroupTypeOrderByGroupNumAsc(courseId, groupType);
	}

	public List<CourseGroupUser> getUserAssignmentGroup(String userId, String assignmentId, String groupType) {
		Assignment assignment = assignmentService.getAssignment(assignmentId);
		CourseGroupUser courseGroupUser = courseGroupUserDao.findCourseGroupUserByCourseIdAndUserIdAndGroupType(assignment.getCourseId(), userId, groupType);
		return courseGroupUserDao.findCourseGroupUserByGroupId(courseGroupUser.getGroupId());
	}

	public List<Student> getStudents(String courseId) {
		List<Student> studentList = new ArrayList<Student>();
		Map<String, Student> map = new HashMap<String, Student>();
		List<CourseGroupUser> courseGroupUserList = courseGroupUserDao.findCourseGroupUserByCourseIdOrderByGroupNameAsc(courseId);
		if (courseGroupUserList != null && !courseGroupUserList.isEmpty()) {
			for (int i = 0; i < courseGroupUserList.size(); i++) {
				User user = userService.findUserById(courseGroupUserList.get(i).getUserId());
				Student student = map.get(user.getId());
				if (student == null)
					student = new Student();
				student.setUserId(user.getId());
				student.setName(user.getRealname());
				student.setStudentNum(user.getUsername());
				student.setEmail(user.getEmail());
				Group group = groupDao.findOne(courseGroupUserList.get(i).getGroupId());
				if (Group.TYPE_SINGLE.equals(group.getGroupType())) {
					student.setSingleNum(group.getGroupNum());
					student.setCommentSingleNum(group.getCommentGroups());
				} else {
					student.setGroupNum(group.getGroupNum());
					student.setCommentGroupNum(group.getCommentGroups());
				}
				map.put(user.getId(), student);
			}
		}
		if (!map.isEmpty()) {
			for (Entry<String, Student> entry : map.entrySet()) {
				studentList.add(entry.getValue());
			}
		}
		return studentList;
	}

	public void updateStudent(String courseId, Student student) {
		if (StringUtil.isValid(courseId)) {
			Course course = getCourseById(courseId);
			if (StringUtil.isValid(student.getUserId())) {
				// 更新用户
				User user = new User();
				user.setUsername(student.getStudentNum());
				user.setPassword("000000");
				user.setRealname(student.getName());
				user.setEmail(student.getEmail());
				user.setRole(User.ROLE_STUDENT);
				user = userService.saveUser(user);

				// 更新组
				Group group = new Group();
				group.setCourseId(course.getId());
				group.setGroupNum(student.getGroupNum());
				group.setGroupName("小组" + student.getGroupNum());
				group.setGroupType(Group.TYPE_GROUP);
				group.setCommentGroups(student.getCommentGroupNum());
				group = groupService.updateGroup(group);

				// 关联组和用户
				CourseGroupUser courseGroupUser = new CourseGroupUser();
				courseGroupUser.setCourseId(course.getId());
				courseGroupUser.setCourseName(course.getCourseName());
				courseGroupUser.setGroupId(group.getId());
				courseGroupUser.setGroupName(group.getGroupName());
				courseGroupUser.setGroupType(Group.TYPE_GROUP);
				courseGroupUser.setUserId(user.getId());
				courseGroupUser.setUserName(user.getRealname());
				courseGroupUserService.updateCourseGroupUser(courseGroupUser);

				// 更新个人组
				if (StringUtil.isValid(student.getSingleNum())) {
					Group singleGroup = new Group();
					singleGroup.setCourseId(course.getId());
					singleGroup.setGroupNum(student.getSingleNum());
					singleGroup.setGroupName("个人" + student.getSingleNum());
					singleGroup.setGroupType(Group.TYPE_SINGLE);
					singleGroup.setCommentGroups(student.getCommentSingleNum());
					singleGroup = groupService.addGroup(singleGroup);

					CourseGroupUser courseSingleGroupUser = new CourseGroupUser();
					courseSingleGroupUser.setCourseId(course.getId());
					courseSingleGroupUser.setCourseName(course.getCourseName());
					courseSingleGroupUser.setGroupId(singleGroup.getId());
					courseSingleGroupUser.setGroupName(singleGroup.getGroupName());
					courseSingleGroupUser.setGroupType(Group.TYPE_SINGLE);
					courseSingleGroupUser.setUserId(user.getId());
					courseSingleGroupUser.setUserName(user.getRealname());
					courseGroupUserService.updateCourseGroupUser(courseSingleGroupUser);
				}
			}
		}

	}

	@Override
	public List<Student> getStudentsByGroupId(String groupId) {
		List<Student> studentList = new ArrayList<Student>();
		Map<String, Student> map = new HashMap<String, Student>();
		List<CourseGroupUser> courseGroupUserList = courseGroupUserDao.findCourseGroupUserByGroupId(groupId);
		if (courseGroupUserList != null && !courseGroupUserList.isEmpty()) {
			for (int i = 0; i < courseGroupUserList.size(); i++) {
				User user = userService.findUserById(courseGroupUserList.get(i).getUserId());
				Student student = map.get(user.getId());
				if (student == null)
					student = new Student();
				student.setUserId(user.getId());
				student.setName(user.getRealname());
				student.setStudentNum(user.getUsername());
				student.setEmail(user.getEmail());
				Group group = groupDao.findOne(courseGroupUserList.get(i).getGroupId());
				if (Group.TYPE_SINGLE.equals(group.getGroupType())) {
					student.setSingleNum(group.getGroupNum());
					student.setCommentSingleNum(group.getCommentGroups());
				} else {
					student.setGroupNum(group.getGroupNum());
					student.setCommentGroupNum(group.getCommentGroups());
				}
				map.put(user.getId(), student);
			}
		}
		if (!map.isEmpty()) {
			for (Entry<String, Student> entry : map.entrySet()) {
				studentList.add(entry.getValue());
			}
		}
		return studentList;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteStudent(String courseId, String userId) {
		CourseGroupUser courseGroupUserG = courseGroupUserDao.findCourseGroupUserByCourseIdAndUserIdAndGroupType(courseId, userId, Group.TYPE_GROUP);
		courseGroupUserDao.delete(courseGroupUserG);
		CourseGroupUser courseGroupUserS = courseGroupUserDao.findCourseGroupUserByCourseIdAndUserIdAndGroupType(courseId, userId, Group.TYPE_SINGLE);
		courseGroupUserDao.delete(courseGroupUserS);
	}

}
